package com.scanner.barcodeservice;

import android.text.TextUtils;

import com.scanner.bean.ScanSetting;
import com.scanner.util.BaseUtils;
import com.scanner.util.LogUtil;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidParameterException;
import java.util.Arrays;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import android_serialport_api.SerialPort;


public class SerialPortManager{
	private static final String TAG = "SerialPortManager";
	
	public static SerialPortManager  mInstance;
		
	private SerialPort mSerialPort = null;
	private OutputStream mOutputStream;
	private InputStream  mInputStream;
	private ReadThread   mReadThread;
	
	private int  mLocalRate  = 0;
	
	private SerialPortListener listener;
	private Lock mlock = new ReentrantLock();
	
	public static Object  mObject = new Object();
	
	public static SerialPortManager getInstance(){
		
		if( mInstance == null){
			mInstance = new SerialPortManager();
		}
		return mInstance;
	}

	public void onDestroySerial(){
		mInstance = null;
	}


    /**
     * 初始化SerialPort？？
     * @return
     * @throws SecurityException
     * @throws IOException
     * @throws InvalidParameterException
     */
	public SerialPort getSerialPort(String serialPortName) throws SecurityException, IOException, InvalidParameterException {
		  
		if (mSerialPort == null) {
			LogUtil.i("调用getSerialPort"+mLocalRate + "；节点=="+serialPortName);
			try {
				//节点，波特率
				mSerialPort = new SerialPort(new File(serialPortName), mLocalRate, 0);
			}catch (Exception e){
				e.printStackTrace();
			}

		}
		
		return mSerialPort;
  }
	

   public void open(int mRate) {
		
		if(mlock.tryLock()){
			mLocalRate = mRate;
			try {
				if( mSerialPort != null){
					mSerialPort.close();
					mSerialPort = null;
				}
				mSerialPort   = getSerialPort(getSerialPortName());//获取串口实例
				if(mSerialPort != null){
					mOutputStream = mSerialPort.getOutputStream();
					mInputStream  = mSerialPort.getInputStream();
				}

				LogUtil.i("打开串口===");
			} catch (InvalidParameterException e) {
				e.printStackTrace();
				LogUtil.e("有问题="+e.toString());
			} catch (SecurityException e) {
				e.printStackTrace();
				LogUtil.e("有问题="+e.toString());
			} catch (IOException e) {
				e.printStackTrace();
				LogUtil.e("有问题="+e.toString());
			}finally{
				mlock.unlock();
			}

		}else{
			LogUtil.e("tryLock  fail");
		}

  }

	private String getSerialPortName(){
		ScanSetting setting = BaseUtils.getSettingFormShare();
		return TextUtils.isEmpty(setting.getSerialPortName()) ? "/dev/ttyMT1" : setting.getSerialPortName();
	}

	 /* 关闭串口设备*/
	public void close() {
		
		if( mSerialPort != null){
			mSerialPort.close();
			mInputStream = null;
			mOutputStream = null;
			mSerialPort = null;
			LogUtil.i("串口关闭");
		}
		
		if(mReadThread != null){
			if (mReadThread.isAlive() ){
				mReadThread.interrupt();
			}
		}
	}
	
	/*向串口写数据*/
	private byte[] bytePre = new byte[] { 0x16, (byte) 0x4D, (byte) 0x0D };

	public int write(String data) {
		int res = 0;
		try {
			mOutputStream.write(bytePre);
			LogUtil.v("串口写数据="+data);
			mOutputStream.write(data.getBytes());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			res = -1;
			e.printStackTrace();
		}
		return 0;
	}

	private  byte[] motoDataStart = {0x04, (byte) 0xe4,0x04,0x00, (byte) 0xff,0x14};//摩托罗拉初始化
	private byte[] wake = new byte[]{0x00};
	public int writeMoto(byte[] data){
		int res = 0;
		try {
			mOutputStream.write(wake);
			try {
				Thread.sleep(20);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			LogUtil.e("写进串口数据"+ Arrays.toString(data));
			if(data != null){
				mOutputStream.write(data);//打开二维码
			}

			mOutputStream.write(wake);
			try {
				Thread.sleep(20);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			mOutputStream.write(motoDataStart);
			try {
				Thread.sleep(20);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		} catch (IOException e) {
			res = -1;
			e.printStackTrace();
		}
		return 0;
	}

	private byte[] idid = {0x04, (byte) 0xC8,0x04,0x00, (byte) 0xFF,0x30};
	private byte[] iiii = new byte[]{0X07, (byte) 0XC6,0X04,0X00, (byte) 0XFF, (byte) 0X8A,0x08, (byte) 0xFD, (byte) 0x9E};
	/*private byte[] ddddd = new byte[]{0X07, (byte) 0XC6,0X04,0X00, (byte) 0XFF, (byte) 0X80,0x00, (byte) 0xFD, (byte) 0xB0};
	private byte[] ccc = new byte[]{0X07, (byte) 0XC6,0X04,0X00, (byte) 0XFF, (byte) 0X9F,0x00, (byte) 0xFD, (byte) 0x91};*/
	public void chushihua(){
		LogUtil.i("初始化记录");
		try {
			mOutputStream.write(wake);

			try {

				Thread.sleep(20);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

			mOutputStream.write(idid);
			try {
				Thread.sleep(20);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			mOutputStream.write(wake);

		} catch (IOException e) {

			e.printStackTrace();
		}
	}

	/*该线程中从串口读取数据*/
	private class ReadThread extends Thread {
		@Override
		public void run() {
			super.run();
			
			while(!isInterrupted()) {
					LogUtil.i("串口读数据");
					int size = -1;
					final byte[] buffer = new byte[2048];

					if (mInputStream == null) return;

					try {
						size = mInputStream.read(buffer);
					}catch (Exception e) {
						e.printStackTrace();
					}

					if (size > 0) {

						LogUtil.e("字节数组=="+ Arrays.toString(buffer));
						LogUtil.e("串口读到的数据="+ new String(buffer, 0, size));
						listener.onResult(new String(buffer, 0, size));
					}
//					LogUtil.e("串口督导的数据=="+size+";mshubju=="+new String(buffer, 0, size));
					try {
						Thread.sleep(150);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
                
				}
			
		}
   }
	
	/*开启从串口读取数据线程*/
	public void read() {
		  mReadThread = new ReadThread();
	      mReadThread.setName("MyReadThread");
	      LogUtil.d("开启线程读取串口数据");
		  mReadThread.start();
	}
	
	/*实现该回调获取数据*/
	public interface SerialPortListener {

		void onResult(String data);
	}
	
	public void setListener(SerialPortListener listener){
		
		SerialPortManager.this.listener = listener;
	}
}
